package com.envoy.testsuite.mvc;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EnumMap;

import javax.swing.JButton;

/**
 * The controller. This communicates between the model and the view.
 * @author Angus J. Goldsmith
 *
 */
public class Controller {

  /**
   * Entry point of the program.
   * @param args command line arguments.
   */
  public static void main(final String[] args) {
    View view = new DummyDeviceManagerView();
    Model model = new DeviceManagerModel();
    Controller controller = new Controller(model, view);
    controller.run();
  }

  /**
   * The model associated with this program.  This runs all the logic.
   */
  private Model model;
  /**
   * The view associated with this program.  This is presented to the user.
   */
  private View view;

  /**
   * Sets up the controller.
   * @param iModel the initial model.
   * @param iView the initial view;
   */
  public Controller(final Model iModel, final View iView) {
    model = iModel;
    view = iView;
  }

  /**
   * Runs the program.
   */
  public final void run() {
    sendListeners();
    view.run();
    boolean readyToRun = false;
    ModelStatus modelStatus = model.setup();
    ModelTransferObject<ViewKey, UpdateType> updateData;
    while (!readyToRun) {
      switch (modelStatus) {
        case Ready:
          updateData = new ModelTransferObject<ViewKey, UpdateType>(
              UpdateType.allIsWell, null);
          view.update(updateData);
          readyToRun = true;
          break;
        case NotConnected:
          updateData = new ModelTransferObject<ViewKey, UpdateType>(
              UpdateType.connectionProblem, null);
          if (view.update(updateData) != 0) {
            System.exit(0);
          } else {
            modelStatus = model.setup();
          }
          break;
        case Catastrophic:
          break;
        default:
          break;
      }
    }
  }

  /**
   * Gives listeners to the view for attaching to various components.
   */
  public final void sendListeners() {
    ButtonListener buttonListener = new ButtonListener();
    ActionListener[] listeners = {buttonListener};
    view.attachListeners(listeners);
  }
  /**
   * Class to listen for button events in the view.
   * @author Angus J. Goldsmith
   *
   */
  private class ButtonListener implements ActionListener {

    /**
     * Checks which button has been pressed and executes appropriate methods.
     * @param event the event fired by the button.
     */
    @Override
    public void actionPerformed(final ActionEvent event) {
      Object eventSource = event.getSource();
      if (eventSource.getClass() == JButton.class) {
        JButton buttonPressed = (JButton) eventSource;
        EnumMap<Parameter, String> parameters;
        ModelTransferObject<Parameter, OperationType> data;
        ModelTransferObject<ViewKey, UpdateType> results;

        switch(buttonPressed.getText()) {
          case "Create Device":
            parameters = view.getParameters(OperationType.createNewDevice);
            data = new ModelTransferObject<Parameter, OperationType>(
                OperationType.createNewDevice, parameters);
            results = model.performOperation(
                data);
            view.update(results);
            break;
          case "Send Message":
            parameters = view.getParameters(OperationType.sendMessage);
            data = new ModelTransferObject<Parameter, OperationType>(
                OperationType.sendMessage, parameters);
            results = model.performOperation(
                data);
            view.update(results);
            break;
          default:
            System.out.println("Wrong button!");
            break;
        }
      }
    }
  }

}
